/**
 * Copyright (c) 2006-2007 Jinyi.lu
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of GNU LGPL license by gun.org
 * which accompanies this distribution, and is available at
 * http://gnu.feld-it.at/copyleft/lesser.html
 * 
 * Project Homepage : http://code.google.com/p/demou
 * Source Code: svn checkout http://demou.googlecode.com/svn/trunk/ demou
 * Mailing list : jinyi.lu@gmail.com
 *                stonelu@126.com
 *
 *  
 * Contributors:
 *     JinYi.Lu - initial API and implementation
 */
package cn.tworen.demou.handler;

import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

import cn.tworen.demou.cmd.CmdName;
import cn.tworen.demou.cmd.DataType;
import cn.tworen.demou.handler.invoke.CloseStream;
import cn.tworen.demou.handler.invoke.Connect;
import cn.tworen.demou.handler.invoke.CreateStream;
import cn.tworen.demou.handler.invoke.DeleteStream;
import cn.tworen.demou.handler.invoke.Disconnect;
import cn.tworen.demou.handler.invoke.FunctionCall;
import cn.tworen.demou.handler.invoke.IInvoke;
import cn.tworen.demou.handler.invoke.Pause;
import cn.tworen.demou.handler.invoke.Play;
import cn.tworen.demou.handler.invoke.Publish;
import cn.tworen.demou.handler.invoke.Seek;
import cn.tworen.demou.rtmp.Client;

/**
 * Created on  2007-1-18
 *
 * Title       : ListenerHandlerFactory.java
 * Description : 
 * 
 * @author     : LuJinYi
 * @version    : 1.0
 * @Date       : 2007-1-18
 * History     : 
 * 
 */
public class ListenerHandlerFactory {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(ListenerHandlerFactory.class);

	//handler map
	private static final Map<DataType, Class> listenerMap  = new HashMap<DataType, Class>();
	//invoke handler map
	private static final Map<CmdName, Class> invokeMap = new HashMap<CmdName, Class>();
	static{
		listenerMap.put(DataType.AUDIO_DATA, AudioDataHandler.class);
		listenerMap.put(DataType.INVOKE, InvokeHandler.class);
		listenerMap.put(DataType.INVOKE_EX, InvokeHandler.class);
		listenerMap.put(DataType.NOTIFY, NotifyHandler.class);
		listenerMap.put(DataType.PING, PingHandler.class);
		listenerMap.put(DataType.VIDEO_DATA, VideoDataHandler.class);
		listenerMap.put(DataType.BYTES_READ, BytesReadHandler.class);
		listenerMap.put(DataType.CHUNK_SIZE, ChunkSizeHandler.class);
		listenerMap.put(DataType.CLIENT_BANDWIDTH, ClientBandwidthHandler.class);
		listenerMap.put(DataType.SERVER_BANDWIDTH, ServerBandwidthHandler.class);
		listenerMap.put(DataType.SHARED_OBJECT, SharedObjectHandler.class);
		listenerMap.put(DataType.SHARED_OBJECT_EX, SharedObjectHandler.class);
		listenerMap.put(DataType.STREAM_METADATA, StreamMetaDataHandler.class);
		listenerMap.put(DataType.STREAM_METADATA_EX, StreamMetaDataHandler.class);
		listenerMap.put(DataType.UNKNOWN, JavaBeanInvokeHandler.class);
	}
	static {
		invokeMap.put(CmdName.closeStream, CloseStream.class);
		invokeMap.put(CmdName.connect, Connect.class);
		invokeMap.put(CmdName.createStream, CreateStream.class);
		invokeMap.put(CmdName.deleteStream, DeleteStream.class);
		invokeMap.put(CmdName.disconnect, Disconnect.class);
		invokeMap.put(CmdName.pause, Pause.class);
		invokeMap.put(CmdName.play, Play.class);
		invokeMap.put(CmdName.publish, Publish.class);
		invokeMap.put(CmdName.functionCall, FunctionCall.class);
		invokeMap.put(CmdName.seek, Seek.class);
	}
	public static void registClientListener(Client client) throws InstantiationException, IllegalAccessException{
		for(DataType dataType: listenerMap.keySet()){
			client.getRoutePacketIn().setListener(dataType, (IListener)listenerMap.get(dataType).newInstance());
		}
	}
	public static void registClientInvokeListener(Client client) throws InstantiationException, IllegalAccessException{
		InvokeHandler invoekHandler  = (InvokeHandler)client.getRoutePacketIn().getListener(DataType.INVOKE);
		InvokeHandler invoekHandlerEx  = (InvokeHandler)client.getRoutePacketIn().getListener(DataType.INVOKE_EX);
		for(CmdName name: invokeMap.keySet()){
			invoekHandler.setListener(name, (IInvoke)invokeMap.get(name).newInstance());
			invoekHandlerEx.setListener(name, (IInvoke)invokeMap.get(name).newInstance());
		}
	}
	public static void setListener(DataType type, Class listener){
		try {
			if (listener.newInstance() instanceof IListener) {
				listenerMap.put(type, listener);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	public static Class getListener(DataType type){
		return listenerMap.get(type);
	}
	public static void setInvokeListener(CmdName name, Class listener){
		try {
			if (listener.newInstance() instanceof IInvoke) {
				invokeMap.put(name, listener);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	public static Class getInvokeListener(CmdName name){
		return invokeMap.get(name);
	}
}
